#include <ros/ros.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <unistd.h>
#include <fcntl.h>
#include <thread>
#include <iostream>
#include "socket_can.hpp"
#include <yaml-cpp/yaml.h>
#include "dbc_file_analysis.h"
#include "dbc_canmsg_unpack.h"
#include "dbc_canmsg_pack.h"
#include "print_can_msg.h"
#include "canmsg_define.h"
#include "util.h"
#include "can_config_data_path.h"

int main(int argc, char **argv)
{
	std::string file_name = can_config_data_path + "can_sender.yaml";
	YAML::Node can_send_node = YAML::LoadFile(file_name); //也可以这样读取文件
	//std::cout << node1["key"].as<double>() << std ::endl;
	socket_can::SocketCAN can_sender(can_send_node["can_device"].as<std::string>());
	double rate = can_send_node["rate"].as<double>();
	ros::init(argc, argv, "can_sender");
	ros::NodeHandle n;
	ros::Rate loop_rate(rate);
	//dbc
	std::string folderpath = can_dbcs_path;
	std::vector<std::string> files;
	getAllFilesInFolder(folderpath, &files);
	for (std::string &file : files)
	{

		dbc_analysis::DbcAnalysis::getInstance()->addOneDbcFile(file);
		std::cout << file << std::endl;
	}

	dbc_analysis::DbcAnalysis::getInstance()->analysisFiles();
	dbc_analysis::DbcAnalysis::getInstance()->printMessages();
	std::cout << can_send_node["messages"] << std::endl;
	std::cout << "msgs size is:" << can_send_node["messages"].size() << std::endl;
	std::vector<int> messages_times_index(can_send_node["messages"].size(), 0);
	std::vector<bool> messages_finish(can_send_node["messages"].size(), false);
	while (1)
	{
		bool temp_flag = true;
		for (int i = 0; i < can_send_node["messages"].size(); i++)
		{
			can_frame frame = {0};
			int max_times = can_send_node["messages"][i]["times"].as<int>();
			if (messages_times_index[i] < max_times)
			{
				std::vector<double> signals_value;
				for (int j = 0; j < can_send_node["messages"][i]["signals"].size(); j++)
				{
					signals_value.push_back(can_send_node["messages"][i]["signals"][j].as<double>());
				}
				//live counter for 0x0a0
				if (can_send_node["messages"][i]["id"].as<int>() == 0x0a0)
				{
					static double live_counter_0a0 = 0;
					if (live_counter_0a0 < 15)
					{
						live_counter_0a0 += 1;
					}
					else
					{
						live_counter_0a0 = 0;
					}
					signals_value[4] = live_counter_0a0;
					std::cout << "live_counter0a0 is:" << live_counter_0a0 << std::endl;
				}
				//live counter for 0x060
				if (can_send_node["messages"][i]["id"].as<int>() == 0x060)
				{
					static double live_counter_060 = 0;
					if (live_counter_060 < 15)
					{
						live_counter_060 += 1;
					}
					else
					{
						live_counter_060 = 0;
					}
					signals_value[5] = live_counter_060;
				}
				std::cout << "signals_value size is:" << signals_value.size() << std::endl;
				int id = can_send_node["messages"][i]["id"].as<int>();
				std::cout << "msg id is:" << id << std::endl;
				//std::cout << "############" << id << std::endl;
				if (can_util::packCanmsg(dbc_analysis::DbcAnalysis::getInstance()
											 ->getMessages()[id],
										 signals_value, frame) == PACK_UNPACK_SUCCESS)

				//std::cout << "############can_id:" << frame.can_id << std::endl;
				{
					//cheack sum 0x0a0
					if (frame.can_id == 0x0a0)
					{
						frame.data[0] = frame.data[1];
						for (int i = 2; i < 8; i++)
						{
							frame.data[0] ^= frame.data[i];
						}
					}

					//cheack sum 0x060
					if (frame.can_id == 0x060)
					{
						frame.data[0] = frame.data[1];
						for (int i = 2; i < 8; i++)
						{
							frame.data[0] ^= frame.data[i];
						}
					}
					can_sender.write_frame(frame);
					msgPrint(frame);
				}
			}
			else
			{
				messages_finish[i] = true;
			}
			temp_flag = temp_flag & messages_finish[i];
			messages_times_index[i]++;
		}
		if (temp_flag == true)
		{
			std::cout << "msgs send finished" << std::endl;
			return 0;
		}
		loop_rate.sleep();
	}
	return 0;
}